// any类型
let an;
an = 1;
an = "hello"; // 不建议使用
let bn: any;
bn = 1;
bn = "hello";
let bbn: string;
bbn = bn; // any 可以赋值给任何类型的变量

// unknown 类型
let cn: unknown;
cn = 1;
cn = "hello";
cn = true;
let cnn: string;
// cnn = cn; //Type 'unknown' is not assignable to type 'string'.
// r若强制赋值，需要进行类型检查或者进行类型断言
cn = "hello";
if (typeof cn === "string") {
  cnn = cn;
}
console.log("cnn ", cnn);

let dn: unknown;
dn = 12345;
let dnn: string = dn as string;
let dnnn: string = <string>dn;
console.log("dnn===" + dnn + ",dnnn===" + dnnn);

// 对象类型
let obj: { name: string; age?: number };
obj = { name: "张三" };
obj = { name: "李四", age: 18 };
console.log("obj", obj);
// propName 表示任意类型属性
let cbj: { name: string; [propName: string]: any };
cbj = { name: "cbj", age: 20 };
cbj = { name: "ccbj", sex: "男" };
console.log("cbj", cbj);

// 函数类型
let fun: (a: number, b: number) => number;
fun = function (a: number, b: number): number {
  return a + b;
};

// & 表示连接 |表示或者
let j: { name: string } & { age: number };
j = { name: "", age: 123 };
// 类型别名
type myType = 1 | 2 | 3 | 4 | 5;
let k: 1 | 2 | 3 | 4 | 5;
let l: 1 | 2 | 3 | 4 | 5;
let m: myType;
k = 1;
l = 2;
m = 3;
console.log("klm", k, l, m);

// 数组类型 两种表达方式
let arr: number[] = [1, 2, 3];
let array: Array<number> = [1, 2, 345];

// 元组类型 长度和类型固定
let yuanArr: [string, number, number];
yuanArr = ["hello", 1, 2];

// 枚举类型
enum Color {
  Red,
  Green,
  Blue,
}
let c: Color = Color.Blue;
console.log(c); // 输出 2
enum Gender {
  male = 0,
  female = 1,
}
let i: { name: string; gender: Gender };
i = { name: "张三", gender: Gender.male };
console.log("i的gender", i.gender === Gender.male);

const getValue = (): number => {
  return 0;
};
//  A 的值是被计算出来的。注意注释部分，如果某个属性的值是计算出来的，那么它后面一位的成员必须要初始化值。
enum List {
  A = getValue(),
  B = 2, // 此处必须要初始化值，不然编译不通过
  C,
}
console.log(List.A); // 0
console.log(List.B); // 2s
console.log(List.C); // 3
function log(str: string): void {
  console.log("hello typeScript");
}

// never 是其它类型（包括 null 和 undefined）的子类型，代表从不会出现的值。这意味着声明为 never 类型的变量只能被 never 类型所赋值，在函数中它通常表现为抛出异常或无法执行到终止点（例如无限循环）
let a: never;
// a = 123 报错
function err(params: string): never {
  throw new Error("错误类型");
}
a = err("123");
console.log(a);
